import { ChromeFilled, LikeOutlined, DislikeOutlined, WarningOutlined, CloseOutlined, CloudUploadOutlined, CopyOutlined, PaperClipOutlined, FileExcelTwoTone, FireOutlined, Html5Outlined, ReadOutlined, RocketOutlined, CaretRightOutlined, SyncOutlined, CheckCircleFilled } from '@ant-design/icons';
import { Attachments, Bubble, Prompts, Sender, useXAgent, useXChat, Welcome } from '@ant-design/x';
import { css } from '@emotion/css';
import { Badge, Button, Divider, Flex, message, Modal, Segmented, Select, Space, Typography, Upload } from 'antd';
import DOMPurify from 'dompurify';
import ReactECharts from 'echarts-for-react';
import hljs from 'highlight.js';
import 'highlight.js/styles/atom-one-dark.css'; // 选择一款主题
import markdownit from 'markdown-it';
import OpenAI from 'openai';
import React, { JSX, useEffect, useMemo, useState, useCallback, useRef } from 'react';
import { useNavigate, useLocation } from 'react-router-dom';
import WT_icon from '../../assets/images/logo0402.svg';
import loading from '../../assets/images/loading.svg';
import renwu from '../../assets/images/renwu.svg';
import bianzu from '../../assets/images/bianzu.svg';
import shendusikao from '../../assets/images/loading.svg';
import { generateRandomNumber } from '../../utils/common';
import { generateHeaders, generateHeadersChat } from '../../utils/header';
import canvasDrawing from './canvasDrawing';
import ChooseSource from './chooseSource';
import './index.less';
const uuidv4 = require('uuid').v4;
import { useSearchParams } from 'react-router-dom';

// 新增类型定义
type ContentType = 'html' | 'text' | 'sql' | 'image' | 'chart' | 'table' | 'think' | 'mcp' | `status@planing` | `plan@${number}@title` | `plan@${number}@content`;

interface AttachedFile {
    uid: string;
    name: string;
    status: 'done' | 'uploading' | 'error';
    type: string;
}
const useStyles = () => (
    {
        containerThink: css({
            position: 'relative',
            margin: '16px 0',
        }),
        containerChart: css({
            position: 'relative',
            margin: '16px 0',
        }),
        headerThink: css({
            width: 'fit-content',
            height: 32,
            display: 'flex',
            alignItems: 'center',
            background: '#f5f5f5',
            borderRadius: 16,
            cursor: 'pointer',
            transition: 'all 0.2s',
        }),
        headerChart: css({
            // width: 130,
            height: 32,
            display: 'flex',
            alignItems: 'center',
            background: '#f5f5f5',
            borderRadius: 8,
            cursor: 'pointer',
            transition: 'all 0.2s',
            marginBottom: 10,
            padding: '0 10px'
        }),
        contentThink: (expanded: boolean) =>
            css({
                overflow: 'hidden',
                transition: 'all 0.3s ease-in-out',
                maxHeight: expanded ? '1000px' : 0,
                borderLeft: '1px dashed #d9d9d9 '
            }),
        contentChart: (expanded: boolean) =>
            css({
                overflow: 'hidden',
                transition: 'all 0.3s ease-in-out',
                maxHeight: expanded ? '1000px' : 0,
            }),
        arrowThink: (expanded: boolean) =>
            css({
                transition: 'transform 0.2s',
                transform: `rotate(${expanded ? 90 : 0}deg)`,
                color: '#666'
            }),
        arrowChart: (expanded: boolean) =>
            css({
                transition: 'transform 0.2s',
                transform: `rotate(${expanded ? 90 : 0}deg)`,
                color: '#666'
            })
    });

// 配置参数
const COMMON_APPID = 'dsjyybai';
const COMMON_APPKEY = 'bb9c5100caf0f84e22d88451e94ce2bb';

// const md = markdownit({ html: true, breaks: true, });

// 先创建基础实例
const baseMd = markdownit({ html: true, breaks: true });

// 重新初始化并扩展配置
const md = markdownit({
    ...baseMd.options, // 继承原有配置
    highlight: (str: string, lang: string) => {
        if (lang && hljs.getLanguage(lang)) {
            try {
                return `<pre class="hljs sql-block"><code>${
                    hljs.highlight(str, {
                        language: lang,
                        ignoreIllegals: true
                    }).value
                    }</code></pre>`;
            } catch (__) { }
        }
        // 使用基础实例的方法进行转义
        return `<pre class="hljs"><code>${baseMd.utils.escapeHtml(str)}</code></pre>`;
    }
});

const defaultConversationsItems = [
    {
        key: JSON.stringify(generateRandomNumber()),
        label: '梧桐数据分析大模型'
    }
];

// 切换大模式
const options = [
    {
        value: 'chatbi-turbo',
        label: 'Analyst-turbo',
        desc: '快速生成数据查询及可视化'
    },
    {
        value: 'chatbi-o1',
        label: 'Analyst-o1',
        desc: '具备先进的深度思考能力'
    },

    {
        value: 'chatbi-pro',
        label: 'Analyst-pro',
        desc: '专业的数据分析专家'
    },
    {
        value: 'chatbi-test',
        label: 'DataManus',
        desc: '强大的思考、规划与执行能力'
    }
];
let client = new OpenAI({
    baseURL: '',
    apiKey: '',
    dangerouslyAllowBrowser: true
});
let base64 = '';
let modelName = 'chatbi-turbo';
// 试用uuid生成sourseKey2
let sourseKey2 = uuidv4(); 
let currentSourceId = '';
let currentSourceName = '';
const Home = () => {    
    const location = useLocation();
    const [displayText, setDisplayText] = useState('选择来源');
    // 添加在其他工具函数附近，例如在useEffect之前
    const convertFileToBase64 = (file: File): Promise<string> => {
        return new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => {
                // 移除data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,前缀
                const base64String = reader.result as string;
                const base64Content = base64String.split(',')[1];
                resolve(base64Content);
            };
            reader.onerror = error => reject(error);
        });
    };


    // 处理会话切换
    useEffect(() => {
        const conversationKey = location.state?.conversationKey;
        const isNew = location.state?.isNew;

        if (conversationKey) {
            // 更新当前活动的会话key
            setActiveKey(conversationKey);

            if (!isNew) {
                // 保存当前会话状态到历史
                setConversationHistory(prev => ({
                    ...prev,
                    [activeKey]: {
                        messages,
                        sourceKey: currentSelectedSource.key,
                        modelName,
                        attachedFiles
                    }
                }));
            }

            // 恢复目标会话状态
            const targetConversation = conversationHistory[conversationKey];
            if (targetConversation) {
                setMessages(targetConversation.messages);
                modelName = targetConversation.modelName;
                setAttachedFiles(targetConversation.attachedFiles || []);
            } else {
                // 新会话初始化
                setMessages([]);
                setAttachedFiles([]);
                // 可能需要重置会话ID
                sourseKey2 = uuidv4();
            }
        }
    }, [location.state]);
    // ==================== State ====================
    const [conversationHistory, setConversationHistory] = useState<{
        [key: string]: {
            messages: any[];
            sourceKey: string;
            modelName: string;
            attachedFiles: any[];
        };
    }>({});
    // ==================== State ====================
    // 状态管理
    const PlanRenderer = ({
        content,
        type,
        planId,
        onClick
    }: {
        content: string;
        type: 'title' | 'content';
        planId: number;
        onClick?: (planId: number) => void;
    }) => {
        if (type === 'title') {
            return (
                <div
                    className="plan-title"
                    // onClick={() => onClick ?.(planId){}}
                    onClick={() => {
                        setLocalShow(true);
                        setAutoShowPanel(true);
                    }}
                    style={{
                        cursor: 'pointer',
                        margin: '8px 0',
                        transition: 'all 0.3s',
                    }}
                >
                    <Space className="bianzu">
                        <img src={bianzu} className="icon" />
                        <span>{content}</span>
                    </Space>
                </div>
            );
        }

        return (
            <div className="plan-content">
                <div dangerouslySetInnerHTML={{ __html: md.render(content) }} />
            </div>
        );
    };
    // 来源弹窗跳转
    const [openRole, setOpenRole] = React.useState(false);
    const [confirmLoadingRole, setConfirmLoadingRole] = React.useState(false);
    const [selectedSource, setSelectedSource] = React.useState<any | null>(null); // 存储子组件传来的 ID
    const [currentSelectedSource, setcurrentSelectedSource] = React.useState<any | null>(null); // 存储子组件传来的 ID
    const handleOkRole = () => {
        setConfirmLoadingRole(true);
        setTimeout(() => {
            setOpenRole(false);
            setConfirmLoadingRole(false);
        }, 2000);
        if (!selectedSource?.key) {
            alert('请先选择来源');
            return;
        }
        setcurrentSelectedSource(selectedSource);
        currentSourceId = selectedSource?.key;
        currentSourceName = selectedSource?.label;
        setOpenRole(false);
    };

    const handleCancelRole = () => {
        setOpenRole(false);
    };

    useEffect(() => {
        if (!currentSelectedSource?.key) {
            return;
        }
        currentSelectedSource?.label
            ? setDisplayText(`来源: ${currentSelectedSource?.label}`)
            : setDisplayText('选择来源');
    }, [currentSelectedSource]); // sourceId 变化时重新获取数据


    const [divHeight, setDivHeight] = React.useState<number>(0);
    const divRef = React.useRef<HTMLDivElement>(null);

    // 获取页面高度
    const getPageHeight = (): number => {
        return Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
    };

    // 调整 div 高度
    const adjustDivHeight = () => {
        const pageHeight = getPageHeight();
        const newHeight = pageHeight - 210;
        if (newHeight > 0) {
            setDivHeight(newHeight);
        } else {
            setDivHeight(0);
        }
    };

    // 监听窗口大小变化
    useEffect(() => {
        if (divRef.current) {
            adjustDivHeight(); // 页面加载时初始化高度
            window.addEventListener('resize', adjustDivHeight);

            // 清理事件监听器
            return () => {
                window.removeEventListener('resize', adjustDivHeight);
            };
        }
    }, []);

    // 监听窗口大小变化事件
    window.addEventListener('resize', adjustDivHeight);

    // 页面加载时也执行一次，确保初始高度正确
    window.addEventListener('load', adjustDivHeight);
    // 在组件中

    const [attachedFiles, setAttachedFiles] = useState<AttachedFile[]>([]);
    const [headerOpen, setHeaderOpen] = React.useState(false);
    const [content, setContent] = React.useState('');
    const [conversationsItems, setConversationsItems] = React.useState(defaultConversationsItems);
    const [activeKey, setActiveKey] = React.useState(defaultConversationsItems[0].key);
    // const [attachedFiles, setAttachedFiles] = React.useState([]);
    const [attachedFilesNew, setAttachedFilesNew] = React.useState<any>({});
    const [searchLoading, setSearchLoading] = React.useState(false);
    const abortRef = React.useRef(false); // 创建一个 ref 来存储中断标志
    const [canvasLoading, setCanvasLoading] = React.useState<boolean>(false);

    // 添加 ref
    const attachmentsRef = React.useRef<any>(null);
    const senderRef = React.useRef<any>(null);

    const [apikey, setApikey] = React.useState('empty');
    const [baseUrl, setBaseUrl] = React.useState(window.config.API_BASE_URL + '/chatbiv3');
    const [selectedValue, setSelectedValue] = useState<string>('chatbi-turbo');

    // 左侧下拉菜单
    const handleChange = (value: string) => {
        // 根据选中的 value 查找对应的选项
        const selectedOption = options.find(opt => opt.value === value);
        if (selectedOption) {
            const { label } = selectedOption;
            setSelectedValue(value);
            messageApi.open({
                type: 'success',
                content: '模式已切换至' + label,
            });
            setApikey('empty');
            setBaseUrl(window.config.API_BASE_URL + '/chatbiv3');
            modelName = value;
        }
    };
    useEffect(() => {
        client = new OpenAI({
            baseURL: baseUrl,
            apiKey: apikey,
            dangerouslyAllowBrowser: true,
            defaultHeaders: generateHeadersChat(
                COMMON_APPID,
                'chatbiv3/chat/completions', // capabilityname
                COMMON_APPKEY
            )
        });
    }, [apikey, baseUrl]);
    // ==================== Runtime ====================

    useEffect(() => {
        // if (activeKey !== undefined) {
        //     setMessages([...messages]);
        // }
        setMessages([]);
    }, [activeKey]);
    // ==================== Event ====================
    // 全局提示
    const [messageApi, contextHolder] = message.useMessage();
    const onSubmit = async (nextContent: any) => {
        if (!nextContent) {
        } else {
            if (attachedFiles.length > 0) {
                // 检查文件类型
                attachedFiles.map((item: any) => {
                    // 检查文件类型
                    const file = (item as unknown as { originFileObj: File }).originFileObj;
                    const suffix = file.name.substr(file.name.lastIndexOf('.'));
                    if (suffix !== '.xls' && suffix !== '.xlsx') {
                        messageApi.open({
                            type: 'warning',
                            content: '仅能处理Excel'
                        });
                        return false;
                    }
                })

                // 转换文件为base64
                try {
                    let files: Array<any> = [];
                    const promises = attachedFiles.map(async (item: any) => {
                        // 检查文件类型
                        const file = (item as unknown as { originFileObj: File }).originFileObj;
                        let filename = file.name;
                        const base64Content = await convertFileToBase64(file);
                        return {
                            content: base64Content,
                            role: filename,
                            source: '',
                            session_id: sourseKey2
                        };
                    });
                    
                    // 等待所有文件处理完成
                    files = await Promise.all(promises);
                    
                    // 创建用户消息
                    const userMessage = {
                        role: 'user',
                        content: nextContent,
                        session_id: sourseKey2,
                    };
                    
                    // 保存文件信息到UI显示
                    setAttachedFilesNew({
                        [messages.length]: {
                            files: attachedFiles,
                            tip: '已上传Excel文件'
                        },
                        ...attachedFilesNew
                    });
                    const multiMessage = {
                        message: nextContent,
                        files: files,
                    }
                    // 现在files数组已包含所有处理好的文件
                    onRequest(JSON.stringify(multiMessage))
                    setContent('');
                    setHeaderOpen(false);
                    setAttachedFiles([]);
                }
                catch (error) {
                    messageApi.open({
                        type: 'error',
                        content: '文件处理失败'
                    });
                }
            } else {
                const multiMessage = {
                    message: nextContent,
                    files: [],
                }
                onRequest(JSON.stringify(multiMessage))
                setContent('');
                setHeaderOpen(false);
            }
        }
    };
    // 流式处理改造
    const [agent] = useXAgent({
        request: async (info, callbacks: any) => {
            const { message, messages } = info;
            const { onSuccess, onUpdate, onError } = callbacks;
            const chatList = [];
            if (message == '') {
                onSuccess('');
            } else {
                try {
                    // 确保message不为undefined再进行解析
                    let messagesStr = message ? JSON.parse(message) : { message: '', files: [] };
                    // 关闭这里的ts检测 
                    // @ts-ignore
                    const stream = await client!.chat.completions.create({
                        model: modelName,
                        messages: [
                            {
                                role: 'user',
                                content: `${messagesStr.message}`
                            } as any,
                            ...messagesStr.files

                        ],
                        user: 'tiantian',
                        stream: true,
                        source_id: currentSourceId,
                        // source: currentSourceName,  // 这里使用了 source 参数
                        cache: false,
                        session_id: sourseKey2,
                    });

                    let buffer = '';
                    let currentType: ContentType = 'text';
                    for await (const chunk of stream) {
                        if (abortRef.current) break;
                        const delta = chunk.choices[0] ?.delta as { content?: string; content_type?: ContentType };
                        const chunkContent = delta ?.content || '';
                        const chunkType = delta ?.content_type || 'text';
                        // 类型切换处理
                        if (chunkType !== currentType) {
                            if (buffer) {
                                chatList.push({ content: buffer, content_type: currentType });
                                onUpdate(chatList);
                                buffer = '';
                            }
                            currentType = chunkType;
                        }

                        buffer += chunkContent;
                        // 实时更新（根据实际需求调整触发频率）
                        if (!chatList.length) {
                            chatList.push({ content: buffer, content_type: currentType });
                        } else {
                            chatList.pop();
                            chatList.push({ content: buffer, content_type: currentType });
                        }
                        onUpdate(chatList);
                    }
                    onSuccess(chatList);
                    base64 = '';
                } catch (error) {
                    console.log('error:', error);
                }
            }
        }
    });

    const { onRequest, messages, setMessages } = useXChat({
        agent
    });

    // 暂停输出
    const handleAbort = () => {
        abortRef.current = true;
    };

    const onPromptsItemClick = (info: any) => {
        if (info.data.key == '1') {
            setOpenRole(true);
        } else {
            onRequest(info.data.description);
        }
    };
    const handleFileChange = (info: any) => {
        setAttachedFiles(info.fileList);
    };
    // 添加复制功能
    const handleCopy = (content: string) => {
        navigator.clipboard.writeText(content);
    };

    // 添加重新生成功能
    const handleRegenerate = (message: string) => {
        if (message) {
            onRequest(message);
        }
    };

    // 画笔功能
    const [drawMode, setDrawMode] = React.useState(false);
    const toggleDrawBtn = (info: any, elClass: string, type: string, elClassBtn: string) => {
        setDrawMode(true);
        canvasDrawing(info, document.querySelector('.' + elClass), type, document.querySelector('.' + elClassBtn));
    };
    const saveBtn = (info: any, elClass: string, type: string) => {
        const canvas = document.querySelector('.' + elClass);
        if (canvas instanceof HTMLCanvasElement) {
            var imageData = canvas.toDataURL('image/png');
            // 找到 <chart> 的位置
            const start = info.message.indexOf('<chart>') + '<chart>'.length;
            const end = info.message.indexOf('</chart>', start);

            // 截取内容
            const chartContent = info.message.slice(start, end);
            setCanvasLoading(true);
            setTimeout(() => {
                setCanvasLoading(false);
            }, 1000);
        } else {
            console.error('The object is not a canvas element.');
        }
        // canvasDrawing(document.querySelector('.' + elClass), type);
    };
    const clearBtn = (info: any, elClass: string, type: string) => {
        canvasDrawing(info, document.querySelector('.' + elClass), type, '');
    };
    // ==================== Nodes ====================

    // 首先定义Excel文件类型白名单
    const EXCEL_MIME_TYPE = [
        'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
        'application/vnd.ms-excel' // .xls
    ];
    // 首页卡片
    const placeholderNode = (
        <Space direction="vertical" size={16} className="placeholder">
            <div className="container">
                <h1>Hello, 我是梧桐数据分析智能体</h1>
                <p className="intro">您在数据分析领域的原⽣数据助理，<br />我可以帮您高效地实现NL2SQL、
                    数据问答、数据分析、数据洞察等多维度的⼤模型智能分析应⽤</p>
                <div className="cards-container">
                    <div className="card-column">
                        <div className="card" onClick={() => handleChange('chatbi-test')}>
                            <div className="card-content">
                            </div>
                        </div>
                    </div>
                    <div className="card-column">
                        <div className="card" onClick={() => {
                            // 设置文本内容
                            setContent("暑期广州热门航线客座率、票价的波动情况？");

                            // 创建新文件对象
                            // const newFile = {
                            //     uid: `excel-${Date.now()}`,
                            //     name: "大数据分析报告.xlsx",
                            //     status: "done" as const,  // 明确指定为字面量类型
                            //     type: EXCEL_MIME_TYPE[0]
                            // };

                            // // 正确更新数组：将新文件添加到数组中
                            // setAttachedFiles(prevFiles => [...prevFiles, newFile]);

                            // // 展开附件面板
                            // setHeaderOpen(true);
                        }}>
                            <div className="card-content">
                                <h3>智能问答</h3>
                                <p>暑期广州热门航线客座率、票价的波动情况？
                                    <br />
                                    <br />
                                </p>
                                {/* 新增文件展示 */}
                                {/* <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: 15 }}>
                                    <FileExcelTwoTone />
                                    <span style={{ fontSize: 12 }}>大数据分析报告.xlsx</span>
                                </div> */}
                            </div>
                        </div>
                        <div className="card"
                            onClick={() => {
                                // 设置文本内容
                                setContent("预测未来6个月的客座率趋势");

                                // 创建新文件对象
                                // const newFile = {
                                //     uid: `excel-${Date.now()}`,
                                //     name: "大数据分析报告.xlsx",
                                //     status: "done" as const,  // 明确指定为字面量类型
                                //     type: EXCEL_MIME_TYPE[0]
                                // };

                                // // 正确更新数组：将新文件添加到数组中
                                // setAttachedFiles(prevFiles => [...prevFiles, newFile]);

                            }}>
                            <div className="card-content">
                                <h3>智能分析</h3>
                                <p>预测未来6个月的客座率趋势</p>
                                {/* 新增文件展示 */}
                                {/* <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: 15 }}>
                                    <FileExcelTwoTone />
                                    <span style={{ fontSize: 12 }}>大数据分析报告.xlsx</span>
                                </div> */}
                            </div>
                        </div>
                    </div>
                    <div className="card-column">
                        <div className="card" onClick={() => {
                            // 设置文本内容
                            setContent("帮我用饼图画出各个产品的市场占有率情况")

                            // 展开附件面板
                            // setHeaderOpen(true);
                        }}>
                            <div className="card-content">
                                <h3>智能图表</h3>
                                <p>帮我用蓝色的折线图展示这个数据</p>
                            </div>
                        </div>
                        <div className="card" onClick={() => {
                            // 设置文本内容
                            setContent("撰写一篇暑期航空市场分析报告");

                            // 创建新文件对象
                            // const newFile = {
                            //     uid: `excel-${Date.now()}`,
                            //     name: "大数据分析报告.xlsx",
                            //     status: "done" as const,  // 明确指定为字面量类型
                            //     type: EXCEL_MIME_TYPE[0]
                            // };

                            // 正确更新数组：将新文件添加到数组中
                            // setAttachedFiles(prevFiles => [...prevFiles, newFile]);

                            // 展开附件面板
                            // setHeaderOpen(true);
                        }}>
                            <div className="card-content">
                                <h3>智能报告</h3>
                                <p>撰写一篇暑期航空市场分析报告</p>
                                {/* 新增文件展示 */}
                                {/* <div style={{ display: 'flex', alignItems: 'center', gap: 8, margin: 15 }}>
                                    <FileExcelTwoTone />
                                    <span style={{ fontSize: 12 }}>大数据分析报告.xlsx</span>
                                </div> */}
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </Space>
    );

    const attachmentsNode = (
        <Badge dot={attachedFiles.length > 0 && !headerOpen}>
            <Button type="text" icon={<PaperClipOutlined />} onClick={() => setHeaderOpen(!headerOpen)} />
        </Badge>
    );

    // 上传附件
    const senderHeader = (
        <Sender.Header
            title="附件"
            open={headerOpen}
            onOpenChange={setHeaderOpen}
            styles={{
                content: {
                    padding: 0
                }
            }}
            forceRender
        >
            <Attachments
                ref={attachmentsRef}
                beforeUpload={(file: { type: string; name: { endsWith: (arg0: string) => unknown; }; }) => {
                    // 严格校验文件类型
                    const isExcel = EXCEL_MIME_TYPE.includes(file.type) ||
                        ['.xlsx', '.xls'].some(ext => file.name.endsWith(ext));

                    if (!isExcel) {
                        message.error('仅支持上传Excel文件（.xls, .xlsx）');
                        return Upload.LIST_IGNORE; // 阻止文件添加
                    }
                    return false; // 阻止自动上传
                }}
                items={attachedFiles}
                onChange={handleFileChange}
                placeholder={type =>
                    type === 'drop'
                        ? {
                            title: '上传附件'
                        }
                        : {
                            icon: <CloudUploadOutlined />,
                            title: '上传附件',
                            description: '点击或者拖拽到这里上传'
                        }
                }
                getDropContainer={() => senderRef.current ?.nativeElement}
            />
        </Sender.Header>
    );

    // html
    const [previewMode, setPreviewMode] = useState<'code' | 'preview'>('code');
    // 安全渲染组件
    const SafePreview = ({ html }: { html: string }) => {
        const iframeRef = React.useRef<HTMLIFrameElement>(null);
        const containerRef = React.useRef<HTMLDivElement>(null);

        // Auto-scroll when HTML content changes
        React.useEffect(() => {
            if (containerRef.current) {
                containerRef.current.scrollTop = containerRef.current.scrollHeight;
            }
        }, [html]);

        // Use iframe for safe rendering
        React.useEffect(() => {
            if (!iframeRef.current) return;

            // Create safe document
            const doc = iframeRef.current.contentDocument;
            if (doc) {
                doc.open();
                doc.write(`
                <!DOCTYPE html>
                <html>
                    <head>
                        <base target="_blank">
                            <style>
                                body {margin: 0; padding: 20px; }
                ${DOMPurify.sanitize(html, { WHOLE_DOCUMENT: true })}
                            </style>
                    </head>
                    <body>
                            ${DOMPurify.sanitize(html)}
                    </body>
                </html>
                    `);
                doc.close();
                
                // Scroll iframe content to bottom
                const scrollToBottom = () => {
                    if (doc.body) {
                        doc.body.scrollTop = doc.body.scrollHeight;
                    }
                };
                
                // Apply scrolling after content loads
                setTimeout(scrollToBottom, 100);
            }
        }, [html]);

        return (
            <div ref={containerRef} style={{ height: '100%', overflowY: 'auto' }}>
                <iframe
                    ref={iframeRef}
                    style={{
                        width: '100%',
                        height: 'calc(100vh - 120px)',
                        border: 'none',
                        borderRadius: 8
                    }}
                    sandbox="allow-scripts allow-same-origin"
                />
            </div>
        );
    };

    const showDrawer = () => {
        setLocalShow(true);
        setAutoShowPanel(true);
    };

    const [expandedThink, setExpandedThink] = useState(true);
    const [expandedChart, setExpandedChart] = useState(true);
    const styles = useStyles();

    // 创建内容渲染器映射
    const CONTENT_RENDERERS: Record<ContentType, (content: string, meta?: any) => JSX.Element> = {
        html: content => (
            <div className="html-container" onClick={showDrawer}>
                <div className="html-header">
                    <Html5Outlined />
                    <div>
                        <span>basic-html</span>
                        <span>基础 HTML 页面</span>
                    </div>
                </div>
                <Divider style={{ margin: '5px 0' }} />
                <div className="html-bottom">
                    <ChromeFilled />
                    <p>生成html</p>
                </div>
            </div>
        ),
        text: content =>
            <div className="html-content-inner" >
                <div dangerouslySetInnerHTML={{ __html: md.render(content) }} />
            </div>,

        // <div className="text-content">{content}</div>,
        sql: content => (
            <div></div>
        ),
        //     (
        //     <pre className="hljs sql-block">
        //         <code>{content}</code>
        //     </pre>
        // ),
        image: content => <img src={content} alt="生成图表" className="inline-image" onError={e => (e.currentTarget.style.display = 'none')} />,
        chart: content => {
            try {
                const option = JSON.parse(content);
                return <div className={styles.containerChart}>
                    <div className={styles.headerChart} onClick={() => setExpandedChart(!expandedChart)}>
                        <CheckCircleFilled style={{ color: '#1677ff' }} />
                        <div style={{
                            marginLeft: 10
                        }}>数据可视化</div>
                        <CaretRightOutlined className={styles.arrowChart(expandedChart)} style={{
                            width: 12,
                            height: 12,
                            marginLeft: 10
                        }} />
                    </div>
                    <div className={styles.contentChart(expandedChart)}>
                        <ReactECharts option={option} style={{ width: '100%', height: 300 }} />
                    </div>
                </div>
            } catch {
                return <div className="chart-error">图表数据解析失败</div>;
            }
        },
        table: content =>
            <div className="html-content-inner" >
                <div dangerouslySetInnerHTML={{ __html: md.render(content) }} />
            </div>,
        think: content => (
            <div className={styles.containerThink}>
                <div className={styles.headerThink} onClick={() => setExpandedThink(!expandedThink)}>
                    <div className="think-title">思考过程</div>
                    <CaretRightOutlined className={styles.arrowThink(expandedThink)} />
                </div>
                <div className={styles.contentThink(expandedThink)}>
                    <div
                        style={{
                            borderRadius: 4,
                            padding: 12,
                        }}
                        dangerouslySetInnerHTML={{ __html: md.render(content) }}
                    />
                </div>
            </div>
        ),
        mcp: content => {
            // Parse the content to remove HTML tags
            const parser = new DOMParser();
            const doc = parser.parseFromString(content, 'text/html');
            const textContent = doc.body.textContent || '';

            return (
                <div className={styles.containerThink}>
                    <div className={styles.headerThink} onClick={() => setExpandedThink(!expandedThink)}>
                        <div className="think-title">MCP处理过程</div>
                        <CaretRightOutlined className={styles.arrowThink(expandedThink)} />
                    </div>
                    <div className={styles.contentThink(expandedThink)}>
                        <div
                            style={{
                                borderRadius: 4,
                                padding: 12,
                            }}
                        >
                            {textContent}
                        </div>
                    </div>
                </div>
            );
        },
        ['status@planing']: content =>
            <div className="plan">
                <span className="text">{content}</span>
                <img src={loading} className="icon" />
            </div>,
        // 使用类型断言处理动态类型
        ['plan@title' as ContentType]: (content: any, planId: any) => (
            <PlanRenderer content={content} type="title" planId={planId} />
        ),
        ['plan@content' as ContentType]: (content: any, planId: any) => (
            <PlanRenderer content={content} type="content" planId={planId} />
        )
    };

    const [localShow, setLocalShow] = useState(true);
    // 第三步：优化 RightContent 组件
    const RightContent = React.memo(({ index, item, itemData }:
        { index: any; item: any; itemData: any }
    ) => {
        const handleClose = useCallback(() => {
            setLocalShow(false);
            setAutoShowPanel(false);
        }, []);
        
        // Add scrollable container ref
        const scrollContainerRef = useRef<HTMLDivElement>(null);
        
        // 添加一个状态来跟踪用户是否手动滚动
        const [userHasScrolled, setUserHasScrolled] = useState(false);

        // 添加滚动事件处理函数
        const handleScroll = useCallback(() => {
            if (!scrollContainerRef.current) return;
            
            const { scrollTop, scrollHeight, clientHeight } = scrollContainerRef.current;
            const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) < 10;
            
            // 如果用户不在底部，标记为已手动滚动
            if (!isAtBottom) {
                setUserHasScrolled(true);
            } else {
                setUserHasScrolled(false);
            }
        }, []);
        
        // 添加滚动事件监听
        useEffect(() => {
            const scrollContainer = scrollContainerRef.current;
            if (scrollContainer) {
                // scrollContainer.addEventListener('scroll', handleScroll);
                // return () => scrollContainer.removeEventListener('scroll', handleScroll);
            }
        }, [handleScroll]);
        
        // 修改自动滚动效果
        useEffect(() => {
            if (scrollContainerRef.current && !userHasScrolled) {
                // 自动滚动到最底部，增加防抖节流
                // scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight;
                scrollContainerRef.current.scrollTo({
                    top: scrollContainerRef.current.scrollHeight,
                    behavior: 'smooth'
                })
                console.log('userHasScrolled');
                // scrollContainerRef.current.scrollTop = scrollContainerRef.current.scrollHeight;
            }
        }, [item.content, userHasScrolled]); // 依赖项增加 userHasScrolled
        
        return (
            <div style={{
                display: localShow && autoShowPanel ? 'block' : 'none',
                width: 500,
                height: '100%',
                flex: localShow && autoShowPanel ? '0 0 30%' : 1,
                transform: 'translateX(0)',
                opacity: 1,
                transition: 'all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1)',
                // boxShadow: '-4px 0 16px rgba(0,0,0,0.1)',
                background: '#fff',
                // overflowY: 'scroll',
                position: 'fixed',
                top: 0,
                right: 0,
            }}>
                {
                    item.content_type == 'html' ?
                        <div>
                            <div
                                style={{
                                    padding: 16,
                                    fontSize: 18,
                                    fontWeight: 'bold',
                                    background: '#f5f5f5',
                                }}>
                                <img src={renwu} style={{ width: 16 }} className="icon" />
                                <span style={{ marginBottom: 24, marginLeft: 10 }}>我的工作站</span> 
                                <CloseOutlined
                                    style={{
                                        position: 'absolute',
                                        right: 25,
                                        top: 20,
                                        cursor: 'pointer',
                                        color: '#999',
                                        fontSize: 22,
                                        zIndex: 1,
                                    }}
                                    onClick={handleClose} />
                            </div>
                            <div
                                style={{
                                    padding: 16,
                                }}>
                                <Space>
                                    <Segmented
                                        value={previewMode}
                                        onChange={(val: string) => setPreviewMode(val as 'code' | 'preview')}
                                        options={[
                                            { value: 'code', label: '实时跟随' },
                                            { value: 'file', label: '文件' },
                                            // { value: 'preview', label: '实时预览' }
                                        ]}
                                    />
                                </Space>
                                {previewMode === 'code' ? (
                                    <div 
                                        className="html-content-container"
                                        ref={scrollContainerRef}
                                        onScroll={handleScroll}
                                        style={{
                                            height: '90vh',    // 固定视口高度
                                            overflowY: 'scroll', // 启用垂直滚动
                                        }}
                                    >
                                        <div className="html-content-inner" dangerouslySetInnerHTML={{ __html: md.render(item.content) }} />
                                    </div>
                                ) : (
                                        <div
                                            style={{
                                                height: '90vh',    // 固定视口高度
                                                overflowY: 'scroll', // 启用垂直滚动
                                            }}>
                                            <SafePreview html={DOMPurify.sanitize(item.content)} />
                                        </div>
                                    )}
                            </div>
                        </div>
                        :
                        <div>
                            <div
                                style={{
                                    padding: 16,
                                    fontSize: 18,
                                    fontWeight: 'bold',
                                    background: '#f5f5f5',
                                }}>
                                <img src={renwu} style={{ width: 16 }} className="icon" />
                                <span style={{ marginBottom: 24, marginLeft: 10 }}>执行计划详情</span>
                                <CloseOutlined
                                    style={{
                                        position: 'absolute',
                                        right: 25,
                                        top: 20,
                                        cursor: 'pointer',
                                        color: '#999',
                                        fontSize: 22,
                                        zIndex: 1,
                                    }}
                                    onClick={handleClose} />
                            </div>
                            <div
                                ref={scrollContainerRef}
                                style={{
                                    padding: 16,
                                    height: '90vh',    // 固定视口高度
                                    overflowY: 'scroll', // 启用垂直滚动
                                }}
                            >
                                <RemoteContent
                                    content={item.content}
                                    contentType={item.content_type}
                                    index={index}
                                    itemData={itemData}
                                />
                            </div>
                        </div>
                }
            </div >
        );
    });

    const [autoShowPanel, setAutoShowPanel] = useState(false);
    // 第一步：将渲染函数转换为正式组件
    const MarkdownItem = ({ itemData, index }: { itemData: any; index: number }) => {
        // 确保所有 hooks 在顶层调用
        const { message: content, status } = itemData;
        const processedContent = useMemo(() => {
            try {
                return content;
            } catch {
                return content;
            }
        }, [content]); // 依赖项明确
        useEffect(() => {
            if (typeof processedContent !== 'string') {
                const hasSpecialContent = processedContent.some((item: any) =>
                    /^plan@\d+@content$/.test(item.content_type) ||
                    item.content_type === 'html'
                );
                setAutoShowPanel(hasSpecialContent);
                // setLocalShow(hasSpecialContent);
            }
        }, [processedContent]);
        return (
            <Typography>
                {status === 'local' ? (
                    <LocalContent content={processedContent} index={index} />
                ) : (
                        processedContent.map((item: any) => (
                            <ContentRenderer
                                key={item.id}
                                item={item}
                                index={index}
                                itemData={itemData}
                                onAutoShowChange={setAutoShowPanel}
                            />
                        ))
                    )}
            </Typography>
        );
    };

    // 第二步：创建独立的内容渲染组件
    const ContentRenderer = React.memo(({ item, index, itemData, onAutoShowChange }:
        { item: any, index: number, itemData: any, onAutoShowChange: (show: boolean) => void }
    ) => {
        // console.log("ContentRenderer", item.content_type);
        // 使用 useEffect 处理显示逻辑
        useEffect(() => {
            const shouldShow = /^plan@\d+@content$/.test(item.content_type) ||
                item.content_type === 'html';
            onAutoShowChange(shouldShow);
            // setLocalShow(shouldShow)
        }, [item.content_type]);
        // console.log(item);

        if (/^plan@\d+@content$/.test(item.content_type)) {
            // onAutoShowChange(true);
            return <RightContent index={index} item={item} itemData={itemData} />;
        }

        if (item.content_type === 'html') {
            // onAutoShowChange(true);
            return (
                <div>
                    <RightContent index={index} item={item} itemData={itemData} />
                    <RemoteContent content={item.content} contentType={item.content_type}
                        index={index} itemData={itemData} />
                </div>
            );
        }

        return <RemoteContent content={item.content} contentType={item.content_type}
            index={index} itemData={itemData} />;
    });

    // 第二步：拆分子组件
    const LocalContent = ({ content, index }: { content: string; index: number }) => (
        <>
            {attachedFilesNew[index] ?.files ?.length > 0 && (
                <Flex vertical gap="middle" style={{ padding: '20px 0' }}>
                    {attachedFilesNew[index].files.map((item: any) => (
                        <Attachments.FileCard key={item.uid} item={item} />
                    ))}
                </Flex>
            )}
            <div dangerouslySetInnerHTML={{ __html: md.render(JSON.parse(content).message) }} />
        </>
    );

    // 第三步：远程内容子组件
    const RemoteContent = ({ content, contentType, index, itemData }: {
        content: string;
        contentType: ContentType;
        index: number;
        itemData: any
    }) => {
        // 解析plan类型
        const planMatch = contentType.match(/^plan@(\d+)@(title|content)$/);

        // 获取渲染器
        const getRenderer = () => {
            if (planMatch) {
                const [, planId, type] = planMatch;
                return type === 'title'
                    ? CONTENT_RENDERERS['plan@title' as ContentType]
                    : CONTENT_RENDERERS['plan@content' as ContentType];
            }
            return CONTENT_RENDERERS[contentType] || CONTENT_RENDERERS.text;
        };

        const renderer = getRenderer();

        return (
            <>
                {/* {contentType === 'chart' ? (
                    <Spin tip="魔法画笔绘制中🪄" spinning={canvasLoading}>
                        <div className="canvasDraw">
                            {renderer(content)}
                            <canvas className={`draw${index}`} style={{ position: 'absolute', top: 0, left: 0 }} />
                        </div>
                    </Spin>
                ) : (
                    renderer(content)
                )} */}
                {/* {contentType === 'chart' && (
                    <div style={{ margin: '10px 0' }}>
                        <Flex gap="small" wrap>
                            <Button
                                className={`toggleDrawBtn${index}`}
                                onClick={() => toggleDrawBtn(itemData, `draw${index}`, 'toggleDrawBtn', `toggleDrawBtn${index}`)}
                                color="primary"
                                variant="filled"
                            >
                                开始绘制
                            </Button>
                            <Button onClick={() => saveBtn(itemData, `draw${index}`, 'saveBtn')} color="primary" variant="filled">
                                保存
                            </Button>
                            <Button onClick={() => clearBtn(itemData, `draw${index}`, 'clearBtn')} color="primary" variant="filled">
                                清除
                            </Button>
                        </Flex>
                    </div>
                )} */}
                {
                    planMatch ? (
                        renderer(content, {
                            planId: parseInt(planMatch[1]),
                            type: planMatch[2]
                        })
                    ) : (
                            renderer(content)
                        )}
            </>
        );
    };

    // 输入框上面功能
    const senderPromptsItems = [
        {
            key: '1',
            description: (
                <div className="source-box">
                    <span>{displayText}</span>
                </div>
            ),
            icon: (
                <RocketOutlined
                    style={{
                        color: '#8c8c8c'
                    }}
                />
            )
        },
        {
            key: '2',
            description: '推荐问题',
            icon: (
                <FireOutlined
                    style={{
                        color: '#8c8c8c'
                    }}
                />
            )
        },
        {
            key: '3',
            description: '查看数据',
            icon: (
                <ReadOutlined
                    style={{
                        color: '#8c8c8c'
                    }}
                />
            )
        }
    ];

    // 使用useRef来存储DOM节点引用
    const messageListRef = useRef<HTMLDivElement>(null);

    // 使用useEffect来监听数据变化并更新UI
    useEffect(() => {
        if (messageListRef.current) {
            // 仅在数据变化时更新DOM
            messageListRef.current.scrollTop = messageListRef.current.scrollHeight;
        }
    }, [messages]);

    // 定义MemoizedBubbleList的props类型
    interface MemoizedBubbleListProps {
        messages: any[];
        localShow: boolean;
        autoShowPanel: boolean;
    }

    // 使用MemoizedBubbleListProps类型
    const MemoizedBubbleList = React.memo(({ messages, localShow, autoShowPanel }: MemoizedBubbleListProps) => (
        <Bubble.List
            style={{ height: headerOpen ? `${divHeight - 100}px` : `${divHeight}px`, maxHeight: headerOpen ? `${divHeight - 100}px` : `${divHeight}px`, margin: '60px 0 0 0' }}
            roles={{
                ai: {
                    placement: 'start',
                    avatar: { icon: <img src={WT_icon} />, style: { background: 'none' } },
                    typing: { step: 5, interval: 20 },
                    style: {
                        marginLeft: localShow && autoShowPanel ? '12px' : '15%',
                        marginRight: localShow && autoShowPanel ? '12px' : '15%',
                        marginTop: 24,
                        width: localShow && autoShowPanel ? '' : '70%',
                        maxWidth: localShow && autoShowPanel ? '' : '70%',
                    }
                },
                user: {
                    placement: 'end',
                    avatar: { icon: <img src={WT_icon} />, style: { background: 'none', display: 'none' } },
                    style: {
                        width: localShow && autoShowPanel ? '' : '30%',
                        marginLeft: localShow && autoShowPanel ? '0%' : '55%',
                        marginRight: localShow && autoShowPanel ? '12px' : '15%',
                    }
                }
            }}
            items={messages.map((item: any, index: number) => {
                const isAI = !!(index % 2);
                return {
                    key: item.id,
                    role: isAI ? 'ai' : 'user',
                    header: isAI ? '梧桐ChatBI' : '',
                    content: <MarkdownItem key={item.id} itemData={item} index={index} />,
                    footer: isAI ? (
                        <Space size={8}>
                            <Button type="text" size="small" icon={<CopyOutlined />} onClick={() => handleCopy(item.message)} />
                            <Button type="text" size="small" icon={<LikeOutlined />} onClick={() => handleCopy(item.message)} />
                            <Button type="text" size="small" icon={<DislikeOutlined />} onClick={() => handleCopy(item.message)} />
                            <Button type="text" size="small" icon={<WarningOutlined />} onClick={() => handleCopy(item.message)} />
                        </Space>
                    ) : (
                        <Space size={8}>
                            <Button type="text" size="small" icon={<SyncOutlined />} onClick={() => handleRegenerate(item.message)} />
                        </Space>
                    )
                };
            })}
        />
    ));

    // ==================== Render =================
    return (

        <div className="chatBI">
            <div className="chat">
                {/* 🌟 消息列表 */}
                <div className="bgImage" ref={divRef}>
                    <Select
                        size="large"
                        value={selectedValue}  // 改为受控模式
                        className="select"
                        variant="borderless"
                        onChange={handleChange}
                        optionRender={(option: any) => (
                            <Space>
                                <div className="optionRender">
                                    <p style={{ margin: '0' }} aria-label={option.data.label}>
                                        {option.data.label}
                                    </p>
                                    <p style={{ margin: '0', fontSize: '12px', color: 'rgba(0,0,0,0.45)' }}>{option.data.desc}</p>
                                </div>
                            </Space>
                        )}
                        options={options}
                    />

                    <div style={{
                        transition: 'all 0.5s ease'
                    }}>
                        {/* 左侧消息列表 */}
                        <div style={{
                            // flex: 1,
                            transition: 'all 0.5s cubic-bezier(0.4, 0, 0.2, 1)',
                            // overflowY: 'auto',
                            paddingRight: localShow && autoShowPanel ? 500 : 0,
                            borderRight: '1px solid #f0f0f0'
                        }}>
                            {
                                messages.length == 0 ?
                                    placeholderNode
                                    :
                                    <MemoizedBubbleList messages={messages} localShow={localShow} autoShowPanel={autoShowPanel} />
                            }
                            <div
                                style={{
                                    width: localShow && autoShowPanel ? 'calc(100% - 786px)' : 'calc(100% - 284px)',
                                    position: 'fixed',
                                    bottom: '20px',
                                    left: localShow && autoShowPanel ? '284px' : '284px'
                                }}
                            >
                                {/* 🌟 输入框 */}
                                {/* 🌟 配置数据+多行输入容器 */}
                                <div style={{
                                    margin: localShow && autoShowPanel ? '15px 10px' : '15px 15%',
                                    border: '1px solid #d9d9d9',
                                    borderRadius: 8,
                                    background: '#fff',
                                    position: 'relative' // 添加相对定位
                                }}>
                                    {/* 配置数据行 - 根据 headerOpen 状态控制显示 */}
                                    <div style={{
                                        borderBottom: headerOpen ? 'none' : '1px solid #f0f0f0', // 同步隐藏边框
                                        fontSize: 12,
                                        color: 'rgba(0, 0, 0, 0.88)',
                                        display: headerOpen ? 'none' : 'block' // 核心控制逻辑
                                    }}>
                                        <Prompts items={senderPromptsItems} onItemClick={onPromptsItemClick} />
                                    </div>

                                    {/* 输入框容器 */}
                                    <div style={{ position: 'relative' }} className={messages.length > 0 ? "has-messages" : ""}>
                                        <Sender
                                            placeholder="您好，我是您的数据助理，请问有什么可以帮您的吗?"
                                            ref={senderRef}
                                            value={content}
                                            header={senderHeader}
                                            onSubmit={onSubmit}
                                            onChange={setContent}
                                            prefix={attachmentsNode}
                                            loading={agent.isRequesting()}
                                            className="adaptive-textarea"
                                            style={{
                                                border: 'none',
                                                boxShadow: 'none',
                                            }}
                                            onPasteFile={file => {
                                                // attachmentsRef.current ?.upload(file);
                                                setHeaderOpen(true);
                                                const extension = file.name.split('.').pop() ?.toLowerCase();
                                                if (extension && ['xls', 'xlsx'].includes(extension)) {
                                                    attachmentsRef.current ?.upload(file);
                                                    setHeaderOpen(true);
                                                } else {
                                                    message.warning('仅支持粘贴Excel文件');
                                                }
                                            }}
                                            onCancel={() => handleAbort()}
                                        />
                                    </div>
                                </div>
                            </div>
                            <div style={{
                                width: localShow && autoShowPanel ? 'calc(100% - 786px)' : 'calc(100% - 284px)',
                            }}
                                className="bottom"
                            ><p>内容由中国移动九天大模型生成，请仔细核对关键数据。</p></div>
                        </div>
                    </div>
                </div>
                <>{contextHolder}</>
                {/* 来源弹窗 */}
                <Modal
                    title="选择来源"
                    width={1200}
                    open={openRole}
                    onOk={handleOkRole}
                    confirmLoading={confirmLoadingRole}
                    onCancel={handleCancelRole}
                    okText="开始对话"
                    cancelText="取消"
                    okButtonProps={{ disabled: !selectedSource?.key }} // 根据 selectedSource 禁用按钮
                >
                    <ChooseSource onSelect={(item: any) => setSelectedSource(item)} />
                </Modal>
            </div>
        </div>
    );
};

export default Home;
